//////////////////////////////////////////////
// ShaderPassMemorySlot.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkGraphics
{
	class Camera ;
	class ShaderPassCustomSlot ;
	class Texture ;
	class System ;
}

namespace nkMaths
{
	class Matrix ;
	class Vector ;
}

/// Includes ---------------------------------

// nkGraphics
#include "ShaderMemorySlot.h"

#include "../../Dll/DllDefines.h"

// nkMemory
#include <NilkinsMemory/Pointers/UniquePtr.h>

/// Class ------------------------------------

namespace nkGraphics
{
	class DLL_GRAPHICS_EXPORT ShaderPassMemorySlot : public ShaderMemorySlot
	{
		public :

			enum class DATA_TYPE
			{
				// Global or unknown
				UNKNOWN = 0,
				VECTOR,
				MATRIX,
				// Often used for post processing
				CAM_CORNERS_WORLD,
				CAM_CORNERS_VIEW,
				TARGET_SIZE,
				PROJECTION_PARAMS,
				TEXTURE_SIZE,
				// Often used in global scene rendering
				VIEW_MATRIX,
				VIEW_MATRIX_INV,
				PROJ_MATRIX,
				PROJ_MATRIX_INV,
				CAM_POSITION,
				CAM_DIRECTION_WORLD,
				// Utility
				TIME,
				// Custom
				CUSTOM
			} ;
		
		public :
		
			// Constructor, destructor
			ShaderPassMemorySlot (System* system) noexcept ;
			virtual ~ShaderPassMemorySlot () ;

			// Getters
			void* getData () const ;
			virtual unsigned int getDataSize () const ;
			virtual nkMemory::StringView getDataTypeAsString () const override ;
			DATA_TYPE getType () const ;
			nkMaths::Vector* getDataAsVector () const ;
			nkMaths::Matrix* getDataAsMatrix () const ;

			// Setters
			void setFromVector (const nkMaths::Vector& data) ;
			void setFromMatrix (const nkMaths::Matrix& data) ;
			void setAsCamCornersWorld (Camera* forcedCamera = nullptr) ;
			void setAsCamCornersView (Camera* forcedCamera = nullptr) ;
			void setAsTargetSize () ;
			void setAsProjectionParameters (Camera* forcedCamera = nullptr) ;
			void setAsViewMatrix (Camera* forcedCamera = nullptr) ;
			void setAsViewMatrixInv (Camera* forcedCamera = nullptr) ;
			void setAsProjectionMatrix (Camera* forcedCamera = nullptr) ;
			void setAsProjectionMatrixInv (Camera* forcedCamera = nullptr) ;
			void setAsCameraPosition (Camera* forcedCamera = nullptr) ;
			void setAsCameraDirectionWorld (Camera* forcedCamera = nullptr) ;
			void setAsTextureSize (Texture* tex) ;
			void setAsTime (unsigned int modulo) ;
			void setAsCustom (nkMemory::UniquePtr<ShaderPassCustomSlot> slot) ;

			// Import / export
			virtual void exportClassToTree (nkExport::Node* rootNode) override ;
			virtual void importClassFromTree (nkExport::Node* rootNode) override ;

		protected :

			// Functions
			// Data erasure
			void _deleteData () ;

		protected :
		
			// Attributes
			// Parent system
			System* _system ;

			// Data and their size
			void* _data ;
			unsigned int _dataSize ;

			// Type currently held
			DATA_TYPE _type ;
	} ;
}